#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include "types.h"
#include "params.h"
#include "defs.h"
#include "preproc.h"
#include "lexer.h"
#include "parser.h"
#include "runtime.h"

extern struct sxbh default_sxbh;
extern struct varh default_varh;

int
test_cl (struct codeline * cl) {
    uint tknum;
    char * h, *t;
    while (cl != NULL) {
        tknum = cl->tknum;
        h = cl->lnstr;
        t = h;
        while (tknum > 0) {
            printf ("[%s] ", h);
            while (*t) t++;
            h = t+1;
            t = h;
            tknum--;
        }
        printf ("\n");
        cl = cl->next;
    }
    return SUCCESS;
}

int
test_token (struct token * tk) {
    while (tk->type != TK_END) {
        switch (tk->type) {
            case TK_COMMA : {
                printf ("[COMMA:%s] ", tk->str);
                break;
            }
            case TK_FUNC : {
                printf ("[FUNC:%s] ", tk->str);
                break;
            }
            case TK_LBL : {
                printf ("[LBL:%s] ", tk->str);
                break;
            }
            case TK_IMM : {
                printf ("[IMM:%llu] ", tk->num);
                break;
            }
            case TK_INS : {
                printf ("[INS:%s] ", tk->str);
                break;
            }
            case TK_REG : {
                printf ("[REG:%s] ", tk->str);
                break;
            }
            case TK_RTC : {
                printf ("[RTC:%s] ", tk->str);
                break;
            }
            case TK_TYPE : {
                printf ("[TYPE:%s] ", tk->str);
                break;
            }
            case TK_STR : {
                printf ("[STR:%s] ", tk->str);
                break;
            }
            case TK_VAR : {
                printf ("[VAR:%s] ", tk->str);
                break;
            }
            case TK_NEXT : {
                printf ("\n");
                break;
            }
            case TK_END:
            case TK_INSVAR:
            break;
        }
        tk = tk->next;
    }
    printf ("\n");
    return SUCCESS;
}

int
test_stls (struct syntaxlist * stls) {
    struct syntaxelem * ste;
    ste = stls->ste;
    while (ste - stls->ste != stls->sz) {
        if (ste->type == SYN_INS) {
            printf ("[INS: T:%d, R:%d %d %d, VN:%s, VT:%d, S:%s, I:%lld]\n", ste->synt.ins.type, 
                    ste->synt.ins.rd, ste->synt.ins.rs1, ste->synt.ins.rs2, ste->synt.ins.varname, ste->synt.ins.vartype ,ste->synt.ins.str, ste->synt.ins.imm);
        }
        if (ste->type == SYN_FUNC) {
            printf ("[FUNC: N:%s]\n", ste->synt.func.name);
        }
        if (ste->type == SYN_LBL) {
             printf ("[LBL: N:%s]\n", ste->synt.lbl.name);
        }
        if (ste->type == SYN_RTC) {
             printf ("[RTC: T:%d]\n", ste->synt.rtc.type);
        }
        if (ste->type == SYN_VAR) {
             printf ("[VAR: N:%s]\n", ste->synt.var.name);
        }
        ste++;
    }
    return SUCCESS;
}

int
test_text (struct textseg * ts) {
    struct ins * i;
    for (i = ts->insls; i - ts->insls < ts->sz; i++) {
        printf ("[INS: T:%d, R:%d %d %d, I:%lld, RT:%d, F:%s, FLG:%d, ASGN:T.%d S.%s I.%lld, CAST:T.%d, J:%u]\n",
        i->type, i->r0, i->r1, i->r2,i->imm, i->rtc, i->func, i->flg,i->asgn.type,i->asgn.str,i->asgn.imm, i->casttype, i->j);
    }
    return 0;
}

int
main (int argc, char ** argv) {
    struct codeline * cl;
    struct token * tk;
    struct textseg * ts;
    struct dataseg * ds;
    struct syntaxlist * stls;
    struct jitngin * jit; 
    struct runtime * rt;
    sxbhinit (&default_sxbh, NR_XBLK);
    ds = getdataseg ();
    varhinit (&default_varh, ds);
    if (argc != 2) {
        printf ("usage: %s ir\n", argv[0]);
        goto error;
    }
    if (access (argv[1], F_OK | R_OK) != 0) {
        printf ("文件不存在.\n");
        goto error;
    }
    if((cl = preprocess (argv[1])) == NULL) {
        printf ("预处理错误.\n");
        goto error;
    }
    if ((tk = scan (cl)) == NULL ||
        (tk = checktoken (tk)) == NULL) {
        printf ("Lexer错误.\n");
        goto error;
    }
    if ((stls = parse (tk)) == NULL) {
        printf ("Parser错误.\n");
        goto error;
    }
    if ((ts = gettextseg (stls, &default_varh)) == NULL) {
        printf ("Parser错误.\n");
        goto error;
    }
    if((jit = getjit (ts, &default_sxbh)) == NULL) {
        printf ("JIT初始化错误.\n");
        goto error;
    }
    if ((rt = getrt (ts, ds, jit, &default_varh)) == NULL) {
        printf ("Runtime初始化错误.\n");
        goto error;
    }
    //ts = gettextseg ()
    // printf ("*** test codeline ***\n");
    // test_cl (cl);
    // printf ("*** test token ***\n");
    // test_token (tk);
    // printf ("*** test stls ***\n");
    // test_stls (stls);
    // printf ("*** test textseg ***\n");
    // test_text (ts);
    ignite (rt);
    //varhinit (&default_varh);
    return EXIT_SUCCESS;
    error:
    return EXIT_FAILURE;
}   